﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using BrainTechLLC;
using BrainTechLLC.WPF;
using DragDropLibrary;
using ImageAppViewModels;

namespace WpfImageDuplicates
{
    /// <summary>
    /// Interaction logic for FilterCollectionView.xaml
    /// </summary>
    public partial class FilterCollectionView : UserControl
    {
        public static readonly DependencyProperty FilterCollectionViewModelProperty =
            DependencyProperty.Register("FilterCollectionViewModel", typeof(FilterCollectionViewModel), typeof(FilterCollectionView), new PropertyMetadata(null, OnFilterCollectionViewModelPropertyChanged));

        public FilterCollectionViewModel FilterCollectionViewModel
        {
            get { return (FilterCollectionViewModel)GetValue(FilterCollectionViewModelProperty); }
            set { SetValue(FilterCollectionViewModelProperty, value); }
        }

        private static void OnFilterCollectionViewModelPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            FilterCollectionView source = d as FilterCollectionView;

            FilterCollectionViewModel v = e.NewValue as FilterCollectionViewModel;

            source.UpdateFilterCollectionViewModel(v);
        }

        private void UpdateFilterCollectionViewModel(FilterCollectionViewModel viewModel)
        {
            this.DataContext = viewModel;
            FilterCollectionViewModel = viewModel;

            CommandBinding cb = new CommandBinding(viewModel.MoveFilterCommand, MoveExecute, MoveCanExecute);
            this.CommandBindings.Add(cb);

            KeyBinding kb = new KeyBinding(GeneralCommands.RemoveSelectedFiltersCommand, new KeyGesture(Key.Delete));
            kb.CommandParameter = viewModel;
            this.InputBindings.Add(kb);
        }

        private void MoveExecute(object sender, ExecutedRoutedEventArgs e)
        {
            DirectionAndFilter p = (DirectionAndFilter)e.Parameter;
            FilterCollectionViewModel.MoveFilterCommand.ExecuteCommand(FilterCollectionViewModel, p._filterVM, p._dir);
        }

        private void MoveCanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            DirectionAndFilter p = (DirectionAndFilter)e.Parameter;
            e.CanExecute = FilterCollectionViewModel.MoveFilterCommand.CanExecute(p._filterCollectionVM, p._filterVM, p._dir);
        }

        public FilterCollectionView()
        {
            InitializeComponent();
            this.DataContext = null;
        }
        
        public void AddFilter(Type type)
        {
            FilterCollectionViewModel.AddFilter(type);
        }

        private void btnAddFilter_Click(object sender, RoutedEventArgs e)
        {
            var types = showAvailable.GetSelectedTypes();

            foreach (var type in types)
            {
                FilterCollectionViewModel.AddFilter(type.Type);
            }

            showAvailable.ClearSelected();
        }

        private void btnClearFilters_Click(object sender, RoutedEventArgs e)
        {
            FilterCollectionViewModel.ClearAllFilters();
        }

        private void showAvailable_WantAdd(object sender, ObjectEventArgs<string> e)
        {
            FilterCollectionViewModel.AddFilter(e.obj);
        }

        private void filterView_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            FilterCollectionViewModel.SetCurrentGeneration(FilterCollectionViewModel.CurrentGeneration + 1, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
        }

        private void RemoveFilter(object sender, ExecutedRoutedEventArgs e)
        {
            FilterViewModel vm = e.Parameter as FilterViewModel;
            FilterCollectionViewModel.RemoveFilter(vm);
        }

        private void RemoveSelectedFilters(object sender, ExecutedRoutedEventArgs e)
        {
            FilterCollectionViewModel vm = e.Parameter as FilterCollectionViewModel;
            List<FilterViewModel> toDelete = new List<FilterViewModel>();

            foreach (var item in lstItems.SelectedItems)
                toDelete.Add(item as FilterViewModel);

            GeneralCommands.RemoveSelectedFiltersCommand.Execute(vm, toDelete);
        }

        private void filterView_Drop(object sender, DragEventArgs e)
        {
        }

        public void DropFilter(DropEventArgs<object> e)
        {
            if (e.DroppedOnto == this.lstItems && DragAndDrop.DragSourceName == "FilterItems")
            {
                UIElement element = lstItems.InputHitTest(e.DropPoint) as UIElement;
                int insertAt = 0;

                if (element != null)
                {
                    var filterView = (element as FrameworkElement).FindParent<FilterView>();

                    if (filterView != null)
                    {
                        for (int n = 0; n < FilterCollectionViewModel.Count; n++)
                        {
                            if (FilterCollectionViewModel[n] == filterView.FilterViewModel)
                            {
                                var top = (double)n * filterView.ActualHeight;
                                var diffY = e.DropPoint.Y - top;
                                if (diffY > filterView.ActualHeight / 2)
                                {
                                    insertAt = n + 1;
                                }
                                else
                                {
                                    insertAt = n;
                                }
                                break;
                            }
                        }
                    }
                    else
                    {

                    }
                }

                ListBox lst = e.DragSource as ListBox;
                var types = lst.GetSelected<TypeViewModel>();

                for (int n = 0; n < types.Count; n++)
                {
                    FilterCollectionViewModel.InsertFilter(types[n].Type, insertAt);
                    insertAt++;
                }
            }
        }        
    }
}
